#include <iostream>
#include <list> //list的头文件
using namespace std;
/*
    1.特点
      list本质是个链表
    2.传授使用函数对象的技巧经验
         谓词函数：一元和二元(形参个数不一样)--》同学问：老师什么时候使用一元谓词？什么时候使用二元谓词？
         规律：看函数的功能，依据函数的功能确定一元还是二元？
         例如：remove_if的功能是删除指定条件的数据，只需要一个参数遍历判断（符合条件就删除）－－》使用一元谓词即可
         　　　sort的功能是排序，排序就涉及到两两比较－－》需要两个参数－－》二元谓词　　
    3.函数符(函数对象)--》后面学习STL算法也要用到
*/

// 定义类重载圆括号
class Test
{
public:
    bool operator()(int n1, int n2) // n1和n2一前一后遍历容器，两两比较
    {
        // 我要求降序:前面的数>后面的数
        return n1 > n2; // n1表示前面的数，n2表示后面的数
    }
};

// 二元谓词
bool fun(int n1, int n2)
{
    // 我要求降序:前面的数>后面的数
    return n1 > n2; // n1表示前面的数，n2表示后面的数
}
int main()
{
    list<int> list1 = {12, 12, 12, 56, 56, 56, 96, 12, 968, 968, 12, 745, 12};
    list<int> list2 = {122, 562, 962, 9682, 7452};

    // 合并
    /*
        1.合并之后，所有的数据都存放到list1里面
        2.合并之后list2被清空
        3.如果list1和list2不提前排好序，合并结果杂乱无序的
    */
    // list1.merge(list2);

    // 删除数据
    /*
        1.如果数据有多个，全部删除
          数据不存在，没有任何变化
    */
    // list1.remove(666); //666不存在,没有任何变化
    // list1.remove(12);

    // 带条件的删除
    /*
        1.官方例子：  list1.remove_if(函数名/类对象)
    */

    // 排序
    // list1.sort(); //默认是升序
    // list2.sort(); //默认是升序
    // 我要降序
    // 使用类对象
    // Test t1;
    // list1.sort(t1);
    // list2.sort(t1);

    // 使用谓词函数
    // list1.sort(fun);
    // list2.sort(fun);

    // 使用Lambda表达式
    // list1.sort([](int n1,int n2){return n1>n2;});
    // list2.sort([](int n1,int n2){return n1<n2;});

    // 把list2插入到list1.begin()的前面，同时清空list2
    // list1.splice(list1.begin(),list2);

    // 去除连续重复的元素
    list1.unique();

    // 迭代器访问容器
    auto it = list1.begin();
    for (; it != list1.end(); it++)
        cout << "list1里面是：" << *it << endl;
    it = list2.begin();
    for (; it != list2.end(); it++)
        cout << "list2里面是：" << *it << endl;
}